﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;


namespace Server
{
    public partial class Form1 : Form
    {
        private Socket server;
        private Socket client;
        private byte[] data = new byte[1024];
        private int Number;

        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            btnStartGame.Enabled = true;
            btnResetGame.Enabled = false;
            btnPlayGame.Enabled = false;
            txtNumber.Enabled = false;
        }

        private void btnStartGame_Click(object sender, EventArgs e)
        {
            //setting variable IP address & Port
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            int port;
            port = int.Parse(txtPortNo.Text);
            IPEndPoint localEP = new IPEndPoint(0, port);
            server.Bind(localEP);
            server.Listen(0); //increases number of backlog requests permitted

            // moved up before begin accept

            //Waiting for first client connection to be requested
            server.BeginAccept(new AsyncCallback(OnConnected), null);
            btnStartGame.Enabled = false;

            txtConnectionStatus.Text = "Waiting for client .....";
            txtNumber.Enabled = true;
            btnStartGame.Enabled = false;
            txtPortNo.Enabled = false;
            btnResetGame.Enabled = false;
            btnPlayGame.Enabled = true;
        }

        //When connection is made by a client
        void OnConnected(IAsyncResult result)
        {
            try
            {
                client = server.EndAccept(result);
                txtConnectionStatus.Text = "Connected to : " + client.RemoteEndPoint;
                data = Encoding.ASCII.GetBytes("Welcome to my server");
                client.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), null);//Parameter for Asynch Method               
            }
            catch (SocketException)
            {
                CloseClient();
            }
        }

        void OnDataReceived(IAsyncResult result)
        {
            try
            {
                //Data has been received using Socket client
                int receive = client.EndReceive(result);
                if (receive == 0) //Count of characters received
                {
                    CloseClient();
                    return;
                }
                else
                {
                    string message = Encoding.ASCII.GetString(data, 0, receive);                    
                    byte[] echomessage;
                    if (message == null || message == "" || message.Contains("\0\0\0") == true)
                    {
                        echomessage = Encoding.ASCII.GetBytes(message);                        
                        client.BeginSend(echomessage, 0, echomessage.Length, SocketFlags.None, new AsyncCallback(OnDataSent), null);
                    }
                    else
                    {
                        int clientNumber;
                        bool isCorrect = false;
                        try
                        {
                            clientNumber = int.Parse(message);
                            if (clientNumber == Number)
                                isCorrect = true;
                            else
                                isCorrect = false;
                        }
                        catch
                        {
                            isCorrect = false;
                        }
                        string dataSent;
                        if (isCorrect)
                            dataSent = "Guess right!";
                        else
                            dataSent = "Guess wrong!";

                        lbxResult.Items.Add(message);
                        echomessage = Encoding.ASCII.GetBytes(dataSent);
                        //Having received message will echo back using appropriate client socket object
                        client.BeginSend(echomessage, 0, echomessage.Length, SocketFlags.None, new AsyncCallback(OnDataSent), null);
                    }
                   
                }
            }
            catch (SocketException)
            {
                CloseClient();
            }
        }

        void OnDataSent(IAsyncResult result)
        {
            try
            {
                //Data has been sent using Socket client
                int sent = client.EndSend(result); //Count of characters sent
                //Begin Async wait to receive data using existing client socket object
                client.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), null);
            }
            catch (SocketException)
            {

                CloseClient();
            }
        }
        
        public void CloseClient()
        {
            client.Close();
            btnStartGame.Enabled = true;
            txtConnectionStatus.Text = "Disconnected";
        }

        private void btnResetGame_Click(object sender, EventArgs e)
        {
            txtNumber.Enabled = true;
            btnResetGame.Enabled = false;
            btnPlayGame.Enabled = true;
            lbxResult.Items.Clear();
        }

        private void btnPlayGame_Click(object sender, EventArgs e)
        {
            try
            {
                Number = int.Parse(txtNumber.Text);
                btnPlayGame.Enabled = false;
                btnResetGame.Enabled = true;
                txtNumber.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Number must be integer!");
            }
        }               
    }
}



